<template>
    <div>
        <!--  normal-page -->
      <div class="divBox" style="margin-top:0;">
            <div style="position: absolute;right:320px;top:30px;z-index:99;">
              <el-button type="primary" @click="saveFlowChart" size="mini">保存流程图</el-button>
              <el-button type="primary" @click="importFlowChart" size="mini">导入流程图</el-button>
            </div>
          <div style="width:1000px;height:750px;">
            <div class="container" ref="container"></div>
          </div>
      </div>
    </div>
  </template>
   
  <script>
  import LogicFlow from "@logicflow/core";
  import "@logicflow/core/lib/style/index.css";
  
  import { DndPanel, SelectionSelect, Control, NodeResize, Menu, InsertNodeInPolyline, Snapshot, } from "@logicflow/extension";
  import "@logicflow/extension/lib/index.css";
  import { getDictDataListApi } from '@/api/form.js'
  import { crudModuleListApi } from '@/api/develop.js'
  import CustomNode from '../js/CustomNode.js'
  
  // import "@logicflow/core/dist/style/index.css"; // 2.0版本前的引入方式
  
  
  export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: "draw",
    data() {
      return {
        lf: null,
        lfMenuData:[],
        autoConnectDistance: 100,
        formgongxu: {
          page: 1,
          limit: 100,
          is_field_all:'',
          is_system: 1,
          order_by:'',
          scope_frame:'all',
          show_search_type: '0',
          view_search: [],
          view_search_boolean: '',
          gongxushezhifuxuan: [['1']]
        },
        importData: {
          nodes: [
            {
              id: '1',
              type: 'rect', // 节点类型为矩形
              x: 100, // 节点的 x 坐标
              y: 100, // 节点的 y 坐标
              text: '节点1' // 节点显示的文本
            },
            {
              id: '2',
              type: 'rect', // 节点类型为圆形
              x: 300, // 节点的 x 坐标
              y: 100, // 节点的 y 坐标
              text: '节点2' // 节点显示的文本
            },
            {
              id: '3',
              type: 'rect', // 节点类型为圆形
              x: 500, // 节点的 x 坐标
              y: 100, // 节点的 y 坐标
              text: '节点3' // 节点显示的文本
            },
            {
              id: '4',
              type: 'rect', // 节点类型为圆形
              x: 700, // 节点的 x 坐标
              y: 100, // 节点的 y 坐标
              text: '节点4' // 节点显示的文本
            }
          ],
          edges: [ // 连接线数据
            {
              sourceNodeId: '1', // 起始节点的 ID
              targetNodeId: '2', // 目标节点的 ID
              type: 'polyline', // 边的类型为折线
              text: '连线', // 边显示的文本
              startPoint: {
                x: 140, // 边起点的 x 坐标
                y: 100 // 边起点的 y 坐标
              },
              endPoint: {
                x: 250, // 边终点的 x 坐标
                y: 100 // 边终点的 y 坐标
              }
            },
            {
              sourceNodeId: '2', // 起始节点的 ID
              targetNodeId: '3', // 目标节点的 ID
              type: 'polyline', // 边的类型为折线
              text: '连线2', // 边显示的文本
              startPoint: {
                x: 350, // 边起点的 x 坐标
                y: 100 // 边起点的 y 坐标
              },
              endPoint: {
                x: 470, // 边终点的 x 坐标
                y: 100 // 边终点的 y 坐标
              }
            },
            {
              sourceNodeId: '3', // 起始节点的 ID
              targetNodeId: '4', // 目标节点的 ID
              type: 'polyline', // 边的类型为折线
              text: '连线3', // 边显示的文本
              startPoint: {
                x: 560, // 边起点的 x 坐标
                y: 100 // 边起点的 y 坐标
              },
              endPoint: {
                x: 650, // 边终点的 x 坐标
                y: 100 // 边终点的 y 坐标
              }
            }
          ]
        },

      };
    },
    // setup() {
    //   const lfRef = ref(null);
    //   return { lfRef };
    // },
    created(){
        // this.handlerCifdata();
    },
  
    mounted() {
      this.getGongxuList();
    },
    methods: {
      handlerFlowInit(){
        this.handlerLogicFlow();
        // setTimeout(()=>{
        //   this.handlerLoadData();
        // },500)
      },
      saveFlowChart() {
        const graphData = this.lf.getGraphData(); // 获取流程图数据
        console.log(graphData); // 在控制台输出，确认数据格式是否正确
        localStorage.setItem("logicflow", JSON.stringify(graphData));
        //  this.lf.getSnapshot() // 下载流程图
      },
      importFlowChart(){
        this.lf.render(this.importData)
      },
      // 字典表数据
      async handlerCifdata(){
        let obj = {
          types: 'gongxvleixing',
          level: 1,
          pid:''
        }
        const result = await getDictDataListApi(obj)
        if(result.status==200){
           let lfMenuData = result.data.list;
           let lfNodeData = []
           for(let i=0;i<lfMenuData.length;i++){
              let obj = {
                id: lfMenuData[i].id,
                type: 'custom-node', // 使用注册的节点类型
                label: lfMenuData[i].name,
                text: lfMenuData[i].name,
                x: 70,
                y: 30,
                className: 'custom-node-class' // 指定CSS类名
              }
              lfNodeData.push(obj)
           }
  
           this.lfMenuData  = lfNodeData;
           this.handlerFlowInit();
        }
      },
      // 工序数据
      async getGongxuList(){
        const result = await crudModuleListApi("gongxushezhong", this.formgongxu)
        if(result.status==200){
           let lfMenuData = result.data.list;
           let lfNodeData = []
           for(let i=0;i<lfMenuData.length;i++){
              let obj = {
                id: lfMenuData[i].gongxudaima, // id
                type: 'custom-node', // 使用注册的节点类型
                label: lfMenuData[i].zhongwenmiaoshu, // gongxudaima
                text: lfMenuData[i].zhongwenmiaoshu,
                x: 70,
                y: 30,
                properties: lfMenuData[i],
                className: 'custom-node-class' // 指定CSS类名
              }
              lfNodeData.push(obj)
           }
  
           this.lfMenuData  = lfNodeData;
           this.handlerFlowInit();
        }
      },
      handlerLoadData(){
         let logicval = localStorage.getItem("logicflow");
         let logicvalue = JSON.parse(logicval);
         console.log("logicvalue", logicvalue)
        //  this.lf.render(logicvalue);
        //  this.lf.updateGraphData(logicvalue)
        // this.lf.changeData(logicvalue)
        // console.log("logicvalue.nodes", logicvalue.nodes)
        // console.log("logicvalue.edges", logicvalue.edges)
        // this.lf.addNode(logicvalue.nodes);
        // this.lf.addEdge(logicvalue.edges);
      },
      handlerLogicFlow(){
        this.lf = new LogicFlow({
          container: this.$refs.container,
          // plugins: [ DndPanel, SelectionSelect,Snapshot, Menu, Control, NodeResize, InsertNodeInPolyline],
          plugins: [SelectionSelect,Snapshot, Menu, DndPanel],
          grid: true,
          // width:'100%',
          // height:'100%',
          background: false,
          stopMoveGraph: false // 允许节点移动

        });
        this.lf.register(CustomNode)
        
        // lfRef.value = lf
        this.lf.extension.dndPanel.setPatternItems(this.lfMenuData)
        this.lf.render();
        console.log("this.lf", this.lf)
        // this.$nextTick(() => {
        //   this.setupConnection();
        // });
        // this.lf.on("node:click", ({ data }) => {
        //   if (data.type === "custom-node") {
        //     console.log("自定义矩形节点被点击", data);
        //     this.$message.success(`点击了自定义节点: ${data.text}`);
        //   }
        // });

        // this.lf.on("node:contextmenu", ({ data }) => {
        //   console.log("右键点击节点:", data);
        //   // 可以在这里处理自定义逻辑
        // });

        this.lf.on('node:drop', ({ data }) => {
          console.log("drops", data)

          
          // 获取附近节点
          setTimeout(() => {
    const nearbyNodes = this.getNearbyNodes(data.id);
    
    if (nearbyNodes.length > 0) {
      const currentNode = this.lf.getNodeModelById(data.id);
      let closestNode = nearbyNodes[0];
      let minDistance = this.calculateDistance(currentNode, closestNode);
      
      for (const node of nearbyNodes) {
        const dist = this.calculateDistance(currentNode, node);
        if (dist < minDistance) {
          minDistance = dist;
          closestNode = node;
        }
      }
      
      this.lf.addEdge({
        type: 'polyline',
        sourceNodeId: data.id,
        targetNodeId: closestNode.id,
      });
    }
  }, 100);
          // if (nearbyNodes.length > 0) {
          //   // 找到最近的节点
          //   const closestNode = this.findClosestNode(data, nearbyNodes);
            
          //   // 创建连接
          //   lf.addEdge({
          //     type: 'your-edge-type',
          //     sourceNodeId: data.id,
          //     targetNodeId: closestNode.id,
          //   });
          // }
        });
        // this.lf.on('node:move', (event) => {
        //   console.log('节点移动事件:', event);
        //   // 处理移动逻辑
        // });
      
        // 监听节点右键菜单事件

        this.lf.setMenuConfig({
          nodeMenu: [
            {
              text: "编辑",
              callback: (node) => {
                console.log("node", node)
                 this.$emit("hadnlerFlowMenu", node, 2)
              },
            },
            {
              text: "删除",
              callback: (node) => {
                this.lf.deleteNode(node.id);
              },
            },
          ],
        });
        this.bindEvents();
      },
      getNearbyNodes(nodeId, distanceThreshold = 100) {
  const currentNode = this.lf.getNodeModelById(nodeId);
  const allNodes = this.lf.getNodes();
  const nearbyNodes = [];
  
  allNodes.forEach(node => {
    if (node.id !== nodeId) {
      const dist = this.calculateDistance(currentNode, node);
      if (dist <= distanceThreshold) {
        nearbyNodes.push(node);
      }
    }
  });
  
  return nearbyNodes;
},

calculateDistance(node1, node2) {
  return Math.sqrt(
    Math.pow(node2.x - node1.x, 2) + 
    Math.pow(node2.y - node1.y, 2)
  );
},
      findClosestNode(currentNode, nodes) {
        // 实现查找最近节点的逻辑
        // 可以根据坐标计算距离
        return nodes[0]; // 简化示例
      },
      init(){
        

        // this.lf.on("node:moving", this.handleNodeMoving);
        //lf.extension.dndPanel.setPatternItems([
          // {
          //   label: '选区',
          //   icon: '',
          //   callback: () => {
          //     lf.extension.selectionSelect.openSelectionSelect();
          //     lf.once('selection:selected', () => {
          //       lf.extension.selectionSelect.closeSelectionSelect();
          //     });
          //   }
          // },
          // {
          //   type: 'circle',
          //   text: '圆形',
          //   label: '圆形',
          //   icon: '',
          // },
          // {
          //   type: 'rect',
          //   label: '矩形',
          //   x: 150,
          //   y: 50,
          //   icon:'',
          //   className: 'important-node'
          // },
          // {
          //   type: 'rect',
          //   label: '系统任务',
          //   icon: '',
          //   className: 'import_icon'
          // },
          // {
          //   type: 'diamond',
          //   label: '条件判断',
          //   icon: '',
          // },
          // {
          //   type: 'circle',
          //   text: '',
          //   label: '结束节点',
          //   icon: '',
          // },
          // {
          //   type: 'polygon',
          //   x: 100,
          //   y: 200,
          //   text: '多边形',
          // },
          // {
       
          //   type: 'text',
          //   x: 100,
          //   y: 200,
          //   width: 100,
          //   height: 50,
          //   icon:'',
          //   text: '文本',
          //   label:'文本'
          // },
        //]);
        
        // this.lf.render();
      },

      bindEvents() {
        // 节点移动事件
        this.lf.on("node:moving", this.handleNodeMoving);
        this.lf.on("node:moveend", this.handleNodeMoveEnd);
        
        // 节点更新后刷新锚点位置
        this.lf.on("node:update", ({ data }) => {
          const nodeModel = this.lf.getNodeModelById(data.id);
          if (nodeModel.updateAnchorPosition) {
            nodeModel.updateAnchorPosition();
          }
        });
      },
      
      // 处理节点移动事件
    handleNodeMoving({ data }) {
      console.log("dataMoving:", data)
      const movingNode = this.lf.getNodeModelById(data.id);
      const allNodes = this.lf.getNodeModelRawData();

      // 排除当前移动的节点
      const otherNodes = allNodes.filter((node) => node.id !== data.id);

      for (const node of otherNodes) {
        const targetNode = this.lf.getNodeModelById(node.id);
        const distance = this.calculateDistance(movingNode, targetNode);

        // 如果距离小于阈值且没有已存在的连线
        if (distance < this.autoConnectDistance && !this.hasConnection(movingNode, targetNode)) {
          this.createConnection(movingNode, targetNode);
          break; // 一次只连接一个最近的节点
        }
      }
    },
    // 计算两个节点之间的距离
    calculateDistance(node1, node2) {
      const dx = node1.x - node2.x;
      const dy = node1.y - node2.y;
      return Math.sqrt(dx * dx + dy * dy);
    },

    // 检查两个节点之间是否已有连线
    hasConnection(sourceNode, targetNode) {
      const edges = this.lf.getEdgeRawData();
      return edges.some(
        (edge) =>
          (edge.sourceNodeId === sourceNode.id &&
            edge.targetNodeId === targetNode.id) ||
          (edge.sourceNodeId === targetNode.id &&
            edge.targetNodeId === sourceNode.id)
      );
    },

    // 创建两个节点之间的连线
    createConnection(sourceNode, targetNode) {
      this.lf.addEdge({
        sourceNodeId: sourceNode.id,
        targetNodeId: targetNode.id,
      });
    },
      setupConnection() {
        let fromNode = null;
        this.lf.on('node:click', ({ data }) => {
          console.log("data", data)
          if (!fromNode) {
            fromNode = data;
            this.lf.updateTextEdges();
          } else {
            this.lf.addEdge({
              type: 'polyline',
              sourceNodeId: fromNode.id,
              targetNodeId: data.id
            });
            fromNode = null;
          }
        });
        
        this.lf.on('blank:click', () => {
          fromNode = null;
        });
      },
  
      
      
    },
  };
  </script>
   
  <style scoped>
  .container {
    display: flex;
    width:auto;
    height: 80vh;
    flex-grow: 1; /*铺满剩余空间*/
    border: 1px solid #ababab;
    overflow: hidden;
    background-color: #fff;
  }
  
  .flex-wrapper {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
  }
  
  *:focus {
    outline: none;
  }
  
  .rect {
    width: 60px;
    height: 50px;
    background: #fff;
    border: 2px solid #000;
  }
  
  .circle {
    width: 50px;
    height: 50px;
    background: #fff;
    border: 2px solid #000;
    border-radius: 50%;
  }
  /deep/ .lf-dndpanel{
     overflow-y: scroll;
     overflow-x: hidden;
     display: flex;
     flex-direction: row;
     flex-wrap: wrap;
     height:730px;
     width:190px;
     justify-content: space-between;
     position: fixed;
     
  }
  .dnd-item {
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    user-select: none;
  }
  
  .wrapper {
    width: 80px;
    height: 50px;
    background: #fff;
    border: 2px solid #000;
  }
  /deep/ .custom-node-class{
     margin-top:0!important;
  }
  /deep/ .custom-node-class .lf-node-body {
    fill: #f0f0f0; /* 背景颜色 */
    stroke: #000;  /* 边框颜色 */
    stroke-width: 2; /* 边框宽度 */
  }
   
  /deep/ .custom-node-class .lf-node-label {
    fill: red; /* 文字颜色 */
    font-size: 14px; /* 文字大小 */
  }
  /deep/ .custom-node-class .lf-dnd-shape{
    height:4px;
  }
  /deep/ .custom-node-class .lf-dnd-text{
    fill: #666; /* 文字颜色 */
    font-size: 12px; /* 文字大小 */
    line-height:14px;
    padding:5px 5px 4px 5px;
    font-weight: 500;
    margin:2px 0;
    cursor: pointer;
    width:80px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: wrap;
    text-align: center;
    border:1px solid #e0e0e0;
    border-radius:2px;
  }
  /deep/ .lf-grid svg{
    display: none!important;
  }
  </style>